import moment from "moment";
import Response, { type ResponseType } from "../servies/response";
import dataBaseInstance from "./dataBase";
import { batchDate } from "./date";
import { type DB } from './DBType';
/**
 * 新增某日账单项
 * @param {DB.Date & DB.EventRecord} { dateId, eventName, amount, changeType } 日期id：日期对应的记录id 事件名称 变动金额 变动类型
 * @return.data boolean true 成功，false 失败
 */
export async function addEventRecord({ dateId, eventName, amount, changeType } : DB.DateId & DB.EventRecord) : Promise<ResponseType<boolean>> {
	const { data } = await queryEventRecord({ dateId });
	const res = await dataBaseInstance.event_record_source.add({ dateId, eventName, amount, changeType, weight: data.length });
	return new Response<boolean>()
		.setData(res ? true : false)
		.toJSON();
}
/**
 * 修改某个事务项
 * @param {DB.EventId & DB.EventRecord} { eventId, eventName, amount, changeType } 
 * @return 
 */
export async function patchEventRecord({ eventId, eventName, amount, changeType } : DB.EventId & DB.EventRecord) : Promise<ResponseType<boolean>> {
	const res = await dataBaseInstance.event_record_source.update(eventId, { eventName, amount, changeType });
	return new Response<boolean>()
		.setData(res ? true : false)
		.toJSON();
}
/**
 * 删除某个事务项
 * @param {EventId} { eventId} 
 * @return 
 */
export async function deleteEventRecord({ eventId } : DB.EventId) : Promise<ResponseType<boolean>> {
	await dataBaseInstance.event_record_source.delete(eventId);
	return new Response<boolean>()
		.setData(true)
		.toJSON();
}

/**
 * 调整endEventId到startEventId之前
 * @param {{startEventId:number,endEventId:number}} {startEventId,endEventId} 
 * @return 
 */
export async function exchangeEventWeight({ startEventId, endEventId, dateId } : { startEventId : number, endEventId : number } & DB.DateId) : Promise<ResponseType<boolean>> {
	const eventList = await dataBaseInstance.event_record_source.where('dateId').equals(dateId).toArray();
	let startIndex = 0;
	let endIndex = 0;
	let arr = eventList.sort((a, b) => a.weight - b.weight).map((v, i) => {
		if (v.eventId === startEventId) {
			startIndex = i;
		}
		if (v.eventId === endEventId) {
			endIndex = i;
		}
		return {
			eventId: v.eventId,
			weight: v.weight,
		}
	})
	arr = arr.slice(startIndex, endIndex + 1);
	let minWeight = arr[0].weight;
	arr.reverse().reduce((t, v) => {
		const weight = v.weight;
		v.weight = t;
		return weight;
	}, minWeight)
	const res = await dataBaseInstance.event_record_source.bulkUpdate(arr.map(v => ({
		key: v.eventId,
		changes: {
			weight: v.weight
		}
	})));
	return new Response<boolean>()
		.setData(res ? true : false)
		.toJSON();
}

/**
 * 查询某天事务记录
 * @param {{string}} dateId 日期id：日期对应的记录id
 * @return.data  事务集合
 */
export async function queryEventRecord({ dateId } : DB.DateId) : Promise<ResponseType<Array<DB.EventRecordSource>>> {
	const recordList = await dataBaseInstance.event_record_source.where('dateId').equals(dateId).toArray();
	return new Response<Array<DB.EventRecordSource>>()
		.setData(recordList.sort((a, b) => a.weight - b.weight))
		.toJSON();
}


/**
 * 查询某个时间段所有事务
 * @param {{ startDate : string, endDate : string, } & DB.ChangeType} { startDate, endDate, changeType } 开始时间与结束时间以及变动类型 时间格式同 date
 * @return.data 结果事务列表 
 */
export async function queryRecordList({ startDate, endDate, changeType } : { startDate : string, endDate : string, } & DB.ChangeType) : Promise<ResponseType<Array<DB.RecordItem>>> {
	const { data, errmsg } = await batchDate({ startDate, endDate });
	if (data.length) {
		const res = await dataBaseInstance.event_record_source
			.where('changeType').equals(changeType)
			.filter(v => data.some(item => item.dateId === v.dateId)).toArray();
		return new Response<Array<DB.RecordItem>>()
			.setData(res.map(item => ({
				...item,
				date: data.find(v => v.dateId === item.dateId).date
			})).sort((a, b) => moment(a.date).valueOf() - moment(b.date).valueOf()))
			.toJSON();
	} else {
		return new Response<Array<DB.RecordItem>>()
			.setData([])
			.setErrmsg(errmsg)
			.toJSON();
	}
}